<template>
  <div
    class="render-top"
    id="canvas-box"
    @dragover="dragoverHandle"
    @dragenter="dragoverHandle"
    @drop="dragHandle"
  >
    <ruler
      :width="50"
      :height="50"
      :perspectiveX="perspectiveX"
      :perspectiveY="perspectiveY"
      :layoutX="layout"
      :scale="scale"
    >
      <template #container>
        <edit-screens
          @handleScroll="handleScroll"
          :scale="scale"
          @handleOtherStop="handleOtherStop"
        >
          <!-- 画布主体 -->
          <div class="go-chart-edit" :style="styleChart">
            <div
              class="go-chart-edit-content"
              :class="{ 'edit-content-border': clickBorder }"
              :style="styleContent"
              @click.stop="handleClickStop"
            >
              <div class="go-chart-edit-filter">
                <!-- 图表组件 可拖拽 -->
                <component-box
                  v-for="(item, index) in getComponentList"
                  :key="item.id"
                  :index="index"
                  :x="item.attr.x"
                  :y="item.attr.y"
                  :w="item.attr.w"
                  :h="item.attr.h"
                  :z="item.zIndex"
                  :parent="true"
                  :is-conflict-check="false"
                  :scale-ratio="scale"
                  :snap="true"
                  :snap-tolerance="5"
                  class-name="my-class"
                  class-name-active="my-active-class"
                  :active="item.id == selectStack && selectCanvas"
                  @resizestop="resizeCallBack"
                  @dragstop="dragCallBack"
                  @activated="activeCallBack(item.id)"
                  @refLineParams="getRefLineParams"
                  @resizing="handleResize"
                  :resizable="item.RESIZE"
                >
                  <div class="go-chart-edit-shape">
                    <component v-if="!item.UPDATE" :is="`lcd-sider-${item.key}`" :key="`lcd-sider-${item.key}~${item.id}`" :id="item.id" :prop="useProp(item.id)" :global="useGlobal(item.id)"></component>
                  </div>
                </component-box>
                <div
                  class="ref-line v-line"
                  v-for="(item) in vLine"
                  :key="item.key"
                  :style="{
                    left: item.position,
                    top: item.origin,
                    height: item.lineLength
                  }"
                />
                <div
                  class="ref-line h-line"
                  v-for="(item) in hLine"
                  :key="item.key"
                  :style="{
                    top: item.position,
                    left: item.origin,
                    width: item.lineLength
                  }"
                />
              </div>
              <!-- 拖拽时智能参考线 -->
            </div>
          </div>
        </edit-screens>
      </template>
    </ruler>
  </div>
</template>

<script>
import { Ruler, EditScreens, ComponentBox } from 'vue-lcd-engine'
import { cloneDeep, useAddKeyboard, useRemoveKeyboard } from '@/utils'

import render from '@/mixins/renderer';

import { lcd_engine_meta } from '@/lcd.engine';

export default {
  name: 'RenderTop',
  mixins: [
    render
  ],
  components: {
    Ruler,
    EditScreens,
    ComponentBox
  },
  computed: {
    styleChart () {
      return {
        width: this.canvasStyle.width * this.scale + this.perspective * this.scale * 2 + 'px',
        height: this.canvasStyle.height * this.scale + this.perspective * this.scale * 2 + 'px',
        padding: this.perspective * this.scale + 'px',
      }
    },
    styleContent () {
      const scale = {
        transform: `scale(${this.scale})`
      }
      return {
        width: this.canvasStyle.width + 'px',
        height: this.canvasStyle.height + 'px',
        ...scale
      }
    },
    border_width () {
      return (1 / this.scale) + 'px'
    },
    border_color () {
      return this.dragStart ? 'transparent' : '#a8a8a8'
    }
  },
  watch: {
    selectStack () {
      this.selectStack && this.handleBorder()
      !this.selectCanvas && this.handleSelectCanvas(true)
    },
    status() {
      if (this.status == '2') {
        this.clickBorder = false
      }
    }
  },
  data () {
    return {
      // width: 2560,
      // height: 1440,
      perspective: 100,
      perspectiveX: 0,
      perspectiveY: 0,
      activeIndex: null,
      vLine: [],
      hLine: [],
      clickBorder: false
    }
  },
  methods: {
    useProp(id) {
      const config = this.getComponentList.find(e => e.id === id);
      // console.log('lcd_engine_meta[config.key]', lcd_engine_meta[config.key])
      if(!config) return {...lcd_engine_meta[config.key].prop};
      return cloneDeep(config.prop)
    },
    useGlobal(id) {
      const config = this.getComponentList.find(e => e.id === id);
      if(!config) return {...lcd_engine_meta[config.key].global};
      return cloneDeep(config.global)
    },
    handleResize(x,y,w,h) {
      console.log('handleResize', x, y, w, h, 'this.selectStack', this.selectStack);
    },
    handleScroll ({ perspectiveX, perspectiveY }) {
      this.perspectiveX = perspectiveX
      this.perspectiveY = perspectiveY
    },
    resizeCallBack (x, y, width, height) {
      this.activeIndex = this.selectStack
      this.handleSetComponet({ x, y, w: width, h: height })
      // 更新
      this.handleUpdateComponent({
        id: this.selectStack,
        key: 'attr',
        value: {
          x,
          y,
          w: width,
          h: height
        },
      });

      this.handleUpdateComponent({
        id: this.selectStack,
        key: 'UPDATE',
        value: true
      })

      this.$nextTick(() => {
        this.handleUpdateComponent({
          id: this.selectStack,
          key: 'UPDATE',
          value: false
        });
      })
    },
    dragCallBack (x, y, width, height) {
      this.activeIndex = this.selectStack
      this.handleSetComponet({ x, y, w: width, h: height })
    },
    handleSetComponet (attr) {
      this.handleUpdateComponent({ id: this.activeIndex, key: 'attr', value: attr, isRecord: true })
    },
    activeCallBack (e) {
      this.activeIndex = e
      this.handleUpdateSelect(e)
      this.handleBorder()
    },
    getRefLineParams (params) {
      let id = 0
      this.vLine = params.vLine.map(e => {//NOSONAR
        return {
          ...e,
          key: ++id
        }
      }).filter(e => e.position)
      this.hLine = params.hLine.map(e => {//NOSONAR
        return {
          ...e,
          key: ++id
        }
      }).filter(e => e.position)
    },
    // 进入拖拽区域
    dragoverHandle (e) {
      e.preventDefault()
      e.stopPropagation()
      if (e.dataTransfer) e.dataTransfer.dropEffect = 'copy'
    },
    dragHandle (e) {
      e.preventDefault()
      try {
        const drayDataString = e?.dataTransfer?.getData('ChartData')
        if (!drayDataString) {
          return
        }
        // 获取组件唯一的 key
        const data = JSON.parse(drayDataString)
        let component = this.createComponent(e, data)
        console.log('component', component);
        this.handleAddComponent(component)
        if (!this.clickBorder) {
          this['handleStatus']('0')
        } else {
          this.handleBorder()
        }
      } catch (error) {
        this.$message.warning('图表正在研发中, 敬请期待...')
      }
    },
    // key 关联对应组件数据
    createComponent (e, data) {
      const { zIndex, key } = data
      console.log('createComponent key', key, lcd_engine_meta[key].attr.w, lcd_engine_meta[key].attr.h);
      const { offsetX, offsetY } = e
      const id = `chart_${new Date().getTime()}`
      this.activeIndex = id
      return {
        attr: {
          x: offsetX,
          y: offsetY,
          w: lcd_engine_meta[key].attr.w,
          h: lcd_engine_meta[key].attr.h
        },
        key: key,
        id,
        zIndex,
        prop: {},
        global: [],
        DELETE: false,
        RESIZE: true,
        UPDATE: false
      }
    },
    handleClickStop (e) {
      const target = Array.from(e.target.classList)
      if (target && target.length) {
        if (target.includes('go-chart-edit-filter')) {
          this.clickBorder = true
          this['handleStatus']('1')
          this.handleUpdateSelect(null)
        } else {
          this.clickBorder = false
          this['handleStatus']('0')
        }
      }
      return false
    },
    handleBorder () {
      if (this.clickBorder) {
        this.clickBorder = false
        this['handleStatus']('0')
      }
    },
    handleOtherStop () {
      if (this.clickBorder) {
        this.clickBorder = false
      }
      if (this.selectStack) {
        this.handleUpdateSelect(null)
      }
      if (this.status != '2') {
        this['handleStatus']('2')
      }
    }
  },
  mounted () {
    useAddKeyboard()
    addEventListener('blur', e => {
      localStorage.setItem('preview', JSON.stringify(this.getComponentList))
      localStorage.setItem('canvasStyle', JSON.stringify(this.canvasStyle))
    })
  },
  beforeDestroy () {
    useRemoveKeyboard()
    removeEventListener('blur', e => {
      console.log('e', e)
    })
    localStorage.setItem('preview', '')
    localStorage.setItem('canvasStyle', '')
  }
}
</script>

<style lang="less" scoped>
@import "~@/styles/vars.less";
.render-top {
  width: 100%;
  height: 100%;
  /deep/ .go-chart-edit {
    box-sizing: border-box;
    &-content {
      background-color: lighten(@dark-color, 13.9% - lightness(@dark-color));
      box-shadow: 0 8px 10px
        rgba(lighten(@dark-color, 11.6% - lightness(@dark-color)), 0.12);
      // border-radius: 10px;
      transform-origin: 0 0;
      background-size: cover;
      overflow: hidden;
      box-sizing: border-box;
      border: 1px solid transparent;
      &.edit-content-border {
        border: 1px solid lighten(@dark-color, 65.84% - lightness(@dark-color));
      }
    }
    &-filter {
      width: inherit;
      height: inherit;
      .my-class {
        position: absolute;
        box-sizing: border-box;
        touch-action: none;
        border-radius: 5px;
        .go-chart-edit-shape {
          position: absolute;
          width: inherit;
          height: inherit;
          box-sizing: border-box;
          pointer-events: none
        }
        &:hover {
          .go-chart-edit-shape {
            border: v-bind("border_width") dashed v-bind("border_color");
          }
        }
      }
      .my-active-class {
        cursor: move;
        .go-chart-edit-shape {
          border: v-bind("border_width") solid v-bind("border_color") !important;
        }
        z-index: 800 !important;
      }
      .draggable {
        cursor: move;
      }
      .ref-line {
        position: absolute;
        background-color: lighten(@dark-color, 65.84% - lightness(@dark-color));
        z-index: 9999;
      }
      .v-line {
        width: v-bind("border_width");
      }
      .h-line {
        height: v-bind("border_width");
      }
    }
    &-shape {
      display: flex;
      justify-content: center;
      align-items: center;
      width: inherit;
      height: inherit;
      border: v-bind("border_width") dashed transparent;
      overflow: hidden;
      img {
        width: 50%;
        height: 50%;
        object-fit: contain;
      }
    }
  }
}
</style>